<?php 

include_once ($GLOBALS['cfgPaths']['lib/dba'].'dbacountries.o.inc.php');
include_once ($GLOBALS['cfgPaths']['lib/dba'].'dbasupplier.o.inc.php');
include_once ($GLOBALS['cfgPaths']['lib/dba'].'dbaPaymentMode.o.inc.php');
include_once ($GLOBALS['cfgPaths']['lib/dba'].'dbaPaymentTrans.o.inc.php');
include_once ($GLOBALS['cfgPaths']['lib/dba'].'dbacurrency.o.inc.php');
include_once ($GLOBALS['cfgPaths']['lib'].'format.o.inc.php');
include_once ($GLOBALS['cfgPaths']['etcPath'].'var_main.inc.php');

class OrderModel
{

    var $currencyInitialized = false;
    var $cart;
    var $cartcount;
    var $deliverer;
    /**
     * Von calcDiscount berechnet, von calcDiscounted verwendet
     */
    var $discount;

    function getInstance()
    {
        static $obj;
        if (!$obj)
            $obj = new OrderModel();
        return $obj;
    }

    function initCart()
    {
        if (!$this->cart)
        {
            $this->cart  = $GLOBALS['env']->getSession('s_cart');
            $this->cartcount = 0;
        }
    }

    function initCurrency()
    {
        if ($this->currencyInitialized)
            return;
        if (!$GLOBALS['inst_dbacurrency'])
            $GLOBALS['inst_dbacurrency'] = new dbacurrency($GLOBALS['udba']);
        $this->rows = $GLOBALS['inst_dbacurrency']->getall();
        for ($i=0;$i<count($this->rows);$i++)
        {
            if ($this->rows[$i]['factor'] == 1)
            {
                $this->priShort   = $this->rows[$i]['short'];
                $this->priDisplay = $this->rows[$i]['display_str'];
            }
        }
        $this->currencyInitialized = true;
    }
    
    function nextCartArticle() 
    {
        $this->initCart();
        //print "test"; print_r($_SESSION['shop_session']); print "test";
        if ($this->cart[$this->cartcount])
        {
            $article = array();
            while (list($name,$value) = each($this->cart[$this->cartcount]))
            {
                $article[$name] = $value;
            }
            $article['subtotal'] = ($this->cart[$this->cartcount]['price'] * $this->cart[$this->cartcount]['quantity']);
            $article['pos'] = $this->cartcount;
            $this->cartcount++;
            return $article;
        }
        else
        {
            $this->cartCount = 0;
        }
    }
    
    function cartArticles()
    {
        $this->initCart();
        return $this->cart;
    }

    function numPosCart()
    {
        $this->initCart();
        return count($this->cart);
    }

    function stdCurrency() {
        $this->initCurrency();
        return $this->priDisplay;
    }

    function _getCountries()
    {
        if (!$this->countries)
        {
            if (!$GLOBALS['dbacountries_inst'])
                $GLOBALS['dbacountries_inst'] = new dbacountries($GLOBALS['udba']);
            $this->countries = $GLOBALS['dbacountries_inst']->getall();
        }
    }

    function _getDeliverers($w_home, $w_abroad)
    {
        if (!$GLOBALS['dbasupplier_inst'])
            $GLOBALS['dbasupplier_inst'] = new dbasupplier($GLOBALS['udba']);
        $this->deliverers = $GLOBALS['dbasupplier_inst']->getSuppliersByArea($w_home, $w_abroad,true);
    }

    function _getDeliverer($id)
    {
        if (!$GLOBALS['dbasupplier_inst'])
            $GLOBALS['dbasupplier_inst'] = new dbasupplier($GLOBALS['udba']);
        return $GLOBALS['dbasupplier_inst']->getSupplierSF($id);
    }

    function _getPaymentModes($w_home, $w_abroad)
    {
        if (!$GLOBALS['dbaPaymentMode_inst'])
            $GLOBALS['dbaPaymentMode_inst'] = new dbaPaymentMode($GLOBALS['udba']);
        $this->paymentModes = $GLOBALS['dbaPaymentMode_inst']->getByAreaLang($w_home, $w_abroad, $GLOBALS['lang_id']);
    }

    function _getPaymentModeName($m_id)
    {
        if (!$GLOBALS['dbaPaymentMode_inst'])
            $GLOBALS['dbaPaymentTrans_inst'] = new dbaPaymentTrans($GLOBALS['udba']);
        $a = $GLOBALS['dbaPaymentTrans_inst']->get($m_id, $GLOBALS['lang_id']);
        return $a['mode'];
    }

    function countrySelect($name, $selected, $firstoption = '')
    {
        $this->_getCountries();
        $html = '<select name="'.$name.'">'."\n";
        if ($firstoption)
        {
            $html .= "<option value=\"\">".$firstoption."</option>\n";
        }
        $html .= "selected:".$selected;
        foreach ($this->countries As $c)
        {
            $html .= '<option value="'.$c['country'].'"';
            if ($selected == $c['country'])
            {
                $html .= ' selected="selected"';
            }
            $html .= '>'.$c['country']."</option>\n";
        }
        $html .= "</select>\n";
        return $html;
    }

    function _isHomeCountry($af, & $w_home, & $w_abroad)
    {
        $this->_getCountries();
        if (!($cust_c = $GLOBALS['env']->param('CUST_ORLAND')))
        {
            $cust_c = $GLOBALS['env']->param('CUST_LAND');
        }
        for ($i = 0; $i < count($this->countries); $i ++)
        {
            if ($this->countries[$i]['country'] == $cust_c)
            {
                $is_home = $this->countries[$i]['home'];
                if ($is_home == 'N')
                {
                    $w_abroad = 'Y';
                }
                else
                {
                    $w_home = 'Y';
                }
                break;
            }
        }
    }

    function deliverySelect($af)
    {
        if (!$this->deliverers)
        {
            $this->_isHomeCountry($shop, $w_home, $w_abroad);
            $this->_getDeliverers($w_home, $w_abroad);
        }
        if (!is_array($this->deliverers))
            return "Configuration Error: Contact Admin";
        $selected = $GLOBALS['env']->param('CUST_DELIVERER');
        $html = '<select name="CUST_DELIVERER">'."\n";
        foreach ($this->deliverers As $s)
        {
            $html .= '<option value="'.$s['id'].'"';
            if ((!empty($selected) && $selected == $s['id']))
            {
                $html .= ' selected="selected"'; 
            }
            $html .= '>'.$s['name']."</option>\n";
        }
        $html .= "</select>\n";
        return $html;
    }

    function paymentSelect($af)
    {
        if (!$this->paymentModes)
        {
            $this->_isHomeCountry($shop, $w_home, $w_abroad);
            $this->_getPaymentModes($w_home, $w_abroad);
        }
        if (!is_array($this->paymentModes))
            return "Configuration Error: Contact Admin";
        $selected = $GLOBALS['env']->param('CUST_PAYMENTMODE');
        $str = '<select name="CUST_PAYMENTMODE">'."\n";
        foreach ($this->paymentModes As $p)
        {
            $str .= '<option value="'.$p['id'].'"';
            if ($p['descr'] == $selected)
            {
                $str .= ' selected="selected"';
            }
            elseif ($p['is_default'] == 'Y')
            {
                $str .= ' selected="selected"';
            }
            $str .= '>'.$p['descr']."</option>\n";
        }
        $str .= "</select>\n";
        return $str;
    }

    function totalTax () 
    {
        $this->initCart();
        if (!$this->totaltax)
        {
            for ($i=0;$i<count($this->cart);$i++)
            {
                $this->totaltax += $this->cart[$i]['taxamount']*$this->cart[$i]['quantity'];
            }
        }
        return $this->totaltax;
    }

    function calcPrice ($amount)
    {
        if (is_array($this->curs)) $this->curs = array();
        for ($i=0;$i<count($this->rows);$i++)
        {
            $this->calc[$this->rows[$i]['short']]['amount']      =  $amount * $this->rows[$i]['factor'];
            $this->calc[$this->rows[$i]['short']]['display_str'] =  &$this->rows[$i]['display_str'];
            if ($this->rows[$i]['factor'] == 1)
            {
                $this->calc[$this->rows[$i]['short']]['priority'] = 1;
            } 
            else
            {
                $this->curs[] = $this->rows[$i]['short'];
            }
        }
    }

    // p1 : separator
    function priceAllCurrencies ($separator)
    {
        $str = '<!--preise_b-->'.$this->getPrice($this->priShort).$separator;
        $arr = array();
        for ($i=0;$i<count($this->curs);$i++)
        {
            $arr[] = $this->getPrice($this->curs[$i]);
        }
        return $str.implode($separator,$arr).'<!--preise_e-->';
    }

    // get Price str p1 : e.g. 'EUR'
    function getPrice ($short)
    {
        $str = $this->currencyStr($this->calc[$short]['amount']);
        if ($this->calc[$short]['priority'])
        {
            $str = $this->mf.$str.' '.$this->calc[$short]['display_str'].$this->mb;
        }
        else
        {
            $str = $this->f.$str.' '.$this->calc[$short]['display_str'].$this->b;
        }
        return $str;
    }

    function currencyStr ($float)
    {
        if ($float < 0)
        {
            $float *= -1;
            $neg        = '-';
        }
        $dec = round($float,2);
        $int = (int) $dec;
        $dec = round(($dec - $int)*100,0);
        if ($dec == 0)
        {
            $dec='00';
        }
        elseif ($dec<10)
        {
            $dec='0'.$dec;
        }
        return $neg.($int.','.$dec);
    }

    function totalPrice () 
    {
        $this->initCart();
        if (!$this->totalPrice)
        {
            for ($i=0;$i<count($this->cart);$i++)
            {
                $this->totalPrice += $this->cart[$i]['quantity']*$this->cart[$i]['price'];
            }
        }
        return $this->totalPrice;
    }

    function totalWeight () 
    {
        $this->initCart();
        if (!$this->totalWeight)
        {
            for ($i=0;$i<count($this->cart);$i++)
            {
                $this->totalWeight += $this->cart[$i]['quantity']*$this->cart[$i]['kg'];
            }
        }
        return $this->totalWeight;
    }
    
    function calcPostage ($id)
    {
        $this->deliverer = $this->_getDeliverer($id);
        include_once($GLOBALS['cfgPaths']['lib'].'cms/shop/postage/'.
            $this->deliverer['postageCalc'].'.o.inc.php');
        $calc = new $this->deliverer['postageCalc']();
        return $calc->calc($this, $id);
    }
    
  // private: for sendreplymail
  function getTranslationArray($meta){
     preg_match('/content="(.*?)"/',$meta,$match);
     $pairs = split(",",$match[1]);
     foreach ($pairs As $p){
       list($name,$value) = split("=",$p);
       $trarr[trim($name)] = trim($value);
     }
     return $trarr;
  }

    function mailBody ($mailcode) 
    {
        global $env;
        $maildata = array();
        if (preg_match('/<meta *name="translation".*?>/im',$mailcode,$matches)){
            $mailcode  = preg_replace('<'.$matches[0].'>',"",$mailcode);
            $trarr     = $this->getTranslationArray($matches[0]);
            $customer  = $env->getSession('cust');
            $s_cart    = $env->getSession('s_cart');
            $stc       = $customer['stdCurrency'];
            $f         = new format();
            $fAddr     = $f->set('<<<<<<<<<<<<<%1:  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<%2');
            $f         = new format();
            $formatTop = $f->set(">>>%1  >>>>>>>>>>>>%2  >>>>>%3   <<<<<<<<<<<<<<<<<<<%4    >>>>>>>>>>>%5  >>>>>>>>>>>>>%6");
            $f         = new format();
            $format    = $f->set(">>>%1  >>>>>>>>>>>>%2  >>>>>%3   <<<<<<<<<<<<<<<<<<<<<%4    >>>>>>>%5 >%6      >>>>>>>%7 >%8");
            $f         = new format();
            $formatBot = $f->set("                           <<<<<<<<<<<<<<<<<<<%1                     >>>>>>>%2 >%3");

            if ($customer['CUST_FIRMA'])
                $billaddress .= $fAddr->getln(array($trarr['firm'],$customer['CUST_FIRMA']));
            $billaddress .= $fAddr->getln(array($trarr['name'],$customer['CUST_NAME']));
            $billaddress .= $fAddr->getln(array($trarr['firstname'],$customer['CUST_VORNAME']));
            $billaddress .= $fAddr->getln(array($trarr['street'],$customer['CUST_STRASSE']));
            $billaddress .= $fAddr->getln(array($trarr['ziptown'],$customer['CUST_PLZ']." ".$customer['CUST_ORT']));
            $billaddress .= $fAddr->getln(array($trarr['country'],$customer['CUST_LAND']));

            if ($customer['CUST_ORNAME']){
                if ($customer['CUST_ORFIRMA'])
                    $deliveryaddress .= $fAddr->getln(array($trarr['firm'],$customer['CUST_ORFIRMA']));
                $deliveryaddress .= $fAddr->getln(array($trarr['name'],$customer['CUST_ORNAME']));
                $deliveryaddress .= $fAddr->getln(array($trarr['firstname'],$customer['CUST_ORVORNAME']));
                $deliveryaddress .= $fAddr->getln(array($trarr['street'],$customer['CUST_ORSTRASSE']));
                $deliveryaddress .= $fAddr->getln(array($trarr['ziptown'],$customer['CUST_ORPLZ']." ".$customer['CUST_ORORT']));
                $deliveryaddress .= $fAddr->getln(array($trarr['country'],$customer['CUST_ORLAND']));
            }
            else
            {
                $deliveryaddress = $billaddress;
            }
        
            $completeorder .= $formatTop->getln(array($trarr['pos'],$trarr['orderno'],$trarr['quantity'],$trarr['descr'],$trarr['price'],$trarr['subtotal']));
            $completeorder .= $formatTop->genFill($formatTop->length,"-")."\n";
            for ($i = 0; $i < count($s_cart); $i++){
                $completeorder .= $format->getln(array($i+1,$s_cart[$i]['orderno'],$s_cart[$i]['quantity'],$s_cart[$i]['name'],$this->currencyStr($s_cart[$i]['price']),$stc,$this->currencyStr($s_cart[$i]['price']*$s_cart[$i]['quantity']),$stc));
            }
            $completeorder .= $format->genFill($format->length,"-")."\n";
            $completeorder .= $formatBot->getln(array($trarr['discount'],$this->currencyStr($customer['discount']+$customer['premium']),$stc));
            $completeorder .= $formatBot->getln(array($trarr['postage'],$this->currencyStr($customer['postage']),$stc));
            $completeorder .= $formatBot->getln(array($trarr['tax'],$this->currencyStr($customer['totalTax']),$stc));
            $completeorder .= $format->genFill($format->length,"-")."\n";
            $completeorder .= $formatBot->getln(array($trarr['total'],$this->currencyStr($customer['totalPrice']),$stc));
            $completeorder .= $format->genFill(27," ").$format->genFill(49,"=")."\n";
            if ($customer['CUST_PAYMENTMODE'] == 5)
                $bankdata = $customer['CUST_BANK']."\nKonto: ".$customer['CUST_KONTO']."\nBLZ: ".$customer['CUST_BLZ']."\n"; 
            $mailcode = preg_replace('/<%= *\$bill_address *%>/im',$billaddress,preg_replace('/<%= *\$delivery_address *%>/im',$deliveryaddress,preg_replace('/<%= *\$complete_order *%>/im',$completeorder,preg_replace('/<%= *\$name *%>/im',$customer['CUST_NAME'],preg_replace('/<%= *\$firstname *%>/im',$customer['CUST_VORNAME'],preg_replace('/<%= *\$paymentmode *%>/im',$this->_getPaymentModeName($customer['CUST_PAYMENTMODE']),preg_replace('/<%= *\$deliverer *%>/im',$customer['CUST_DELIVERER'],preg_replace('/<%= *\$bankdata *%>/im',$bankdata,$mailcode))))))));
         }
         $maildata['subject'] = $trarr['subject'];
         $maildata['body']    = $mailcode;
         $maildata['email']   = $customer['CUST_EMAIL'];
         return $maildata;
    }

    function loadMailTemplate ($type = 'reply')
    {
        $fname  = $GLOBALS['cfgPaths']['etcPath'] . "replymail/" . $GLOBALS['lang_name'] . "_".$type."mail.is";
        if (file_exists($fname))
        {
            $fp = fopen($fname,"r");
            while (!feof($fp))
            {
                $mailcode .= fgets($fp,500000);
            }
            fclose($fp);
        } 
        else
        {
            print "loaderror";
        }    
        return $mailcode;
    }

    function sendMails()
    {
        $mailarr = array();
        if ($GLOBALS['cfgXICSShop']['sendReply'])  
        {
            $mailarr = $this->mailBody($this->loadMailTemplate('reply'));
            $mailarr['from'] = $GLOBALS['cfgXICSShop']['replyMailFrom'];
            mail($mailarr['email'],
                $mailarr['subject'],
                $mailarr['body'],
                "From: " . $GLOBALS['cfgXICSShop']['replyMailFrom']."\r\n" .
                        "Content-Type: text/plain; charset=ISO-8859-1\r\n\r\n");
        }
        if ($GLOBALS['cfgXICSShop']['sendNotify'])
        {
            $mailarr = $this->mailBody($this->loadMailTemplate('notify'));
            $mailarr['email'] = $GLOBALS['cfgXICSShop']['notificationMailTo'];
            $mailarr['from'] = $GLOBALS['cfgXICSShop']['replyMailFrom'];
            mail($mailarr['email'],
                $mailarr['subject'],
                $mailarr['body'],
                "From: " . $GLOBALS['cfgXICSShop']['replyMailFrom']."\r\n" .
                        "Content-Type: text/plain; charset=ISO-8859-1\r\n\r\n");
        }
    }    
    
    function getDeliverer($id)
    {
        if (!$this->deliverer)
            $this->deliverer = $this->_getDeliverer($id);
        return $this->deliverer;
    }
    
    function getPaymentMode ($mode)
    {
        if (!$GLOBALS['inst_dbaPaymentMode'])
            $GLOBALS['inst_dbaPaymentMode'] = new dbaPaymentMode($GLOBALS['udba']);
        return $GLOBALS['inst_dbaPaymentMode']->get($mode);
    }

    function containedTax ($amount, $tax)
    {
        return $amount-($amount/(($tax+100)/100));
    }

    /*
    
    
    */
    function initActionForm(& $af)
    {
        $af->set('stdCurrency', $this->stdCurrency());
        $af->set('numPosCart', $this->numPosCart());
        $af->set('cart', $this->cartArticles());
        // Gesamtpreis und Steuern
        $totalTax   = $this->totalTax();
        $totalPrice = $this->totalPrice();
        $af->set('subTotal',    round($totalPrice, 2));
        $af->set('subTotalTax', round($totalTax, 2));
        
        // PaymentMode Rabatt/Aufschlag
        $pm = $this->getPaymentMode($af->get('CUST_PAYMENTMODE'));
        
        if ($pm['amount'])
        {
            // Aufschlag
            $af->set('paymentPricePremium', $pm['amount']);
            $af->set('premium', round($pm['amount'], 2));
            $af->set('premiumTax', round($this->containedTax($pm['amount'],$pm['tax']), 2));
            $totalPrice  += $pm['amount'];
            $totalTax    += $af->get('premiumTax');
        }
        elseif ($pm['percent'])
        {
            // Gesamtpreis und Steuern mit Rabatt
            $af->set('paymentDiscount', $pm['percent']);
            $factor = $pm['percent'] / 100;
            $af->set('discountTax', round(-1 * ($totalTax * $factor), 2));
            $af->set('discount', round(-1 * ($totalPrice * $factor), 2));
            $totalPrice  += $af->get('discount');
            $totalTax    += $af->get('discountTax');
        }

        $postage = $this->calcPostage($af->get('CUST_DELIVERER'));
        $af->set('postage', round($postage['cost'], 2));
        $af->set('postageTax', round($this->containedTax($af->get('postage'),$this->deliverer['tax']), 2));
        if ($postage['amount'])
        {
            $af->set('calcBasis', $af->currencyAsStr($postage['amount'], $af->get('stdCurrency')));
        }
        else
        {
            $af->set('calcBasis', $postage['quantity'].' '.$postage['unit']);
        }
        $af->set('totalTax',   round($totalTax + $af->get('postageTax'), 2));
        $af->set('totalPrice', round($totalPrice + $af->get('postage'), 2));

        $this->calcPrice($af->get('totalPrice'));
        $af->set('total', $this->priceAllCurrencies('<br/>'));
    }

}

?>